#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cstring>
#include <arpa/inet.h>
#include <cstdlib>
#include <json-c/json.h>
#include <filesystem>

#define PORT 9090
#define BUFFER_SIZE 2048
#define FILE_SIZE 64

struct Fileinfo
{
    char name[FILE_SIZE];
    size_t size;
};

struct Datainfo
{
    int num;
    char data[BUFFER_SIZE];
};

typedef struct Fileinfo Fileinfo;
typedef struct Datainfo Datainfo;

int main(int argc, char *argv[])
{
    /*创建通信文件描述符*/
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
        perror("socket create error");
        _exit(-1);
    }

    /*连接服务器*/
    sockaddr_in serverAddress;
    /*地址族IPV4*/
    serverAddress.sin_family = AF_INET;
    /*端口*/
    serverAddress.sin_port = htons(PORT);
    /*服务器ip地址*/
    const char *servereIp = "192.168.175.131";
    // 将 servereIp 中的 IPv4 地址（例如 "192.168.1.1"）转换成网络字节序的 32 位整数，
    // 并将其存储在 serverAddress.sin_addr.s_addr 中
    inet_pton(AF_INET, servereIp, &(serverAddress.sin_addr.s_addr));

    char path[BUFFER_SIZE] = {0};
    memset(path, 0, sizeof(path));
    printf("请输入发送信息路径:");
    fgets(path, sizeof(path), stdin);
    path[strcspn(path, "\n")] = 0; // 去掉末尾的换行符

    int fd = open(path, O_RDONLY);
    struct stat statinfo;
    memset(&statinfo, 0, sizeof(statinfo));
    stat(path, &statinfo);

    // 发送文件类型 和 文件大小
    Fileinfo information;
    strncpy(information.name, path, FILE_SIZE - 1); // 使用strncpy防止溢出
    information.name[FILE_SIZE - 1] = '\0';         // 确保字符串以'\0'结尾

    sendto(sockfd, &information, sizeof(information), 0, (const struct sockaddr *)&serverAddress, sizeof(serverAddress));

    char data[BUFFER_SIZE] = {0};
    int total = 0;
    int readBytes = 0;
    int sendBytes = 0;
    Datainfo datainfo;
    memset(&datainfo, 0, sizeof(datainfo));
    int num = 1;
    // 发送端代码修改
    while (total < statinfo.st_size)
    {
        readBytes = read(fd, data, BUFFER_SIZE);
        if (readBytes < 0)
        {
            perror("read error!");
            exit(-1);
        }

        datainfo.num = num;

        memcpy(datainfo.data, data, readBytes); // 使用实际读取的字节数

        sendBytes = sendto(sockfd, &datainfo, sizeof(Datainfo), 0, (const struct sockaddr *)&serverAddress, sizeof(serverAddress));
        total += readBytes;
        memset(&datainfo, 0, sizeof(datainfo));
        num++;
    }
    // 发送结束标志
    memset(&datainfo, 0, sizeof(datainfo));
    datainfo.num = -1; // 特殊标志表示传输结束
    sendBytes = sendto(sockfd, &datainfo, sizeof(Datainfo), 0, (const struct sockaddr *)&serverAddress, sizeof(serverAddress));
    printf("文件上传完成\n");

    close(sockfd);
    close(fd);
    return 0;
}